using System;
using System.Collections.Generic;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
using NTrace;

namespace NTrace.Tasks
{
  public class EtwTrace : Task
  {
    private ITaskItem[] sources;
    private ITaskItem[] ignore;
    private List<ITaskItem> results;
    private String outputFolder;
    private String etwProviderVariable;
    private Guid providerId;
    private String friendlyName = String.Empty;
    private int functionTraceFlag = 0;
    private byte functionTraceLevel = 0;
    private String traceClassName = "EtwTrace";
    private String traceLevelName = "EtwTraceLevel";
    private String traceFlagName = "EtwTraceFlag";
    private String buildFlavor = "Debug";

    public EtwTrace()
    {
    }

    public ITaskItem[] Ignore
    {
      get
      {
        return this.ignore;
      }
      set
      {
        this.ignore = value;
      }
    }

    [Required]
    public ITaskItem[] Sources
    {
      get
      {
        return this.sources;
      }
      set
      {
        this.sources = value;
      }
    }

    [Output]
    public ITaskItem[] Results
    {
      get
      {
        return this.results.ToArray();
      }
    }

    public String OutputFolder
    {
      get
      {
        return this.outputFolder;
      }
      set
      {
        this.outputFolder = value;
      }
    }

    [Required]
    public String EtwProviderVariable
    {
      get
      {
        return this.etwProviderVariable;
      }
      set
      {
        this.etwProviderVariable = value;
      }
    }

    [Required]
    public String ProviderId
    {
      get
      {
        return this.providerId.ToString("D");
      }
      set
      {
        this.providerId = new Guid(value);
      }
    }

    [Required]
    public String FriendlyName
    {
      get
      {
        return this.friendlyName;
      }
      set
      {
        this.friendlyName = value;
      }
    }

    public int FunctionTraceFlag
    {
      get
      {
        return this.functionTraceFlag;
      }
      set
      {
        this.functionTraceFlag = value;
      }
    }

    public Byte FunctionTraceLevel
    {
      get
      {
        return this.functionTraceLevel;
      }
      set
      {
        this.functionTraceLevel = value;
      }
    }

    public String TraceClassName
    {
      get
      {
        return this.traceClassName;
      }
      set
      {
        this.traceClassName = value;
      }
    }

    public String TraceLevelName
    {
      get
      {
        return this.traceLevelName;
      }
      set
      {
        this.traceLevelName = value;
      }
    }

    public String TraceFlagName
    {
      get
      {
        return this.traceFlagName;
      }
      set
      {
        this.traceFlagName = value;
      }
    }

    public String BuildFlavor
    {
      get
      {
        return this.buildFlavor;
      }
      set
      {
        this.buildFlavor = value;
      }
    }

    public override bool Execute()
    {
      List<String> sourceFiles = new List<String>();
      List<String> ignoreFiles = new List<String>();
      this.results = new List<ITaskItem>();

      if (this.sources != null && this.sources.Length > 0)
      {
        for (int index = 0; index < this.sources.Length; index++)
        {
          if (this.sources[index] != null)
          {
            sourceFiles.Add(this.sources[index].GetMetadata("FullPath"));
          }
        }
      }

      if (this.ignore != null && this.ignore.Length > 0)
      {
        for (int index = 0; index < this.ignore.Length; index++)
        {
          if (this.ignore[index] != null)
          {
            ignoreFiles.Add(this.ignore[index].ItemSpec);
          }
        }
      }

      List<String> processedFiles = new List<String>();

      NTrace.Environment environment = new NTrace.Environment();
      environment.OutputFolder = this.OutputFolder;
      environment.EtwProviderVariable = this.EtwProviderVariable;
      environment.ProviderId = this.providerId;
      environment.FriendlyName = this.FriendlyName;
      environment.FunctionTraceFlag = this.FunctionTraceFlag;
      environment.FunctionTraceLevel = this.FunctionTraceLevel;
      environment.TraceClassName = this.TraceClassName;
      environment.TraceLevelName = this.TraceLevelName;
      environment.TraceFlagName = this.TraceFlagName;
      environment.BuildFlavor = this.BuildFlavor;

      FileProcessor processor = new FileProcessor(environment);
      foreach (String targetFile in sourceFiles)
      {
        if (ignoreFiles.Contains(targetFile))
        {
          results.Add(new TaskItem(targetFile));
        }
        else
        {
          String preprocessedFile = processor.Process(targetFile);

          results.Add(new TaskItem(preprocessedFile));
        }
      }

      return true;
    }
  }
}
